<html>
<head><meta charset="utf-8"><title>Using ODR linkage for generics? · t-compiler/wg-llvm · Zulip Chat Archive</title></head>
<h2>Stream: <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/index.html">t-compiler/wg-llvm</a></h2>
<h3>Topic: <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html">Using ODR linkage for generics?</a></h3>

<hr>

<base href="https://rust-lang.zulipchat.com">

<head><link href="https://rust-lang.github.io/zulip_archive/style.css" rel="stylesheet"></head>

<a name="185580208"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/185580208" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Björn Steinbrink <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#185580208">(Jan 14 2020 at 10:02)</a>:</h4>
<p>When I recently looked at the v0 name mangling scheme, I was confused why generics had a suffix that is not based on the crate that defined the generic, but the one that instantiated it, because that makes using ODR linkage to avoid duplicate function definitions in the final binary impossible due to different symbol names.  I then looked through the code and noticed that ODR linkage is gone. We used to use ODR linkage for generics when codegen units were introduced, but it seems to have been removed when incremental compilation has been introduced. Is that because there were problems that completely prohibit ODR linkage in the context of incremental compilation, or was it just the easier approach at the time? After all, the old name mangling scheme made ODR across crates impossible as well, but I had hoped that the new one would allow for it.</p>



<a name="185615386"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/185615386" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> pnkfelix <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#185615386">(Jan 14 2020 at 16:58)</a>:</h4>
<p>cc <span class="user-mention" data-user-id="124287">@mw</span> ^</p>



<a name="185684613"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/185684613" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> mw <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#185684613">(Jan 15 2020 at 10:16)</a>:</h4>
<p>I don't think there are conceptual reasons for not using ODR linkage. If I remember correctly the reasons we removed it were:</p>
<ul>
<li>The MingW toolchain had problems with it </li>
<li>LLVM was less aggressive about optimizing some things</li>
<li>It's simpler to only have two kinds of linkage instead of three</li>
</ul>
<p>However, that was a long time ago (2016?) and those reasons might not be valid anymore. In fact, I hoped that I or someone else would look into reenabling ODR linkage in the first half of this year. It would make some things easier to implement and it might reduce code size (maybe even compile times?)</p>
<p>Questions that would need clarification:</p>
<ul>
<li>Does ODR linkage adversely affect runtime performance?</li>
<li>Would we use "available_externally" linkage too?</li>
<li>Is ODR linkage well enough supported on all relevant platforms? (I'd hate having to keep around the current logic for having copies of the same code)</li>
</ul>
<p>The new mangling scheme supports those "instantiating crate" suffixes because the compiler currently needs them. But the suffixes could just be omitted.</p>



<a name="198527937"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/198527937" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#198527937">(May 23 2020 at 09:53)</a>:</h4>
<p>Looking back at some old issues, the MingW issue seems to be related specifically to the use of weak symbols. I'm wondering why weak_odr rather than linkonce_odr was used at the time.</p>



<a name="198528982"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/198528982" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Hanna Kruppe <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#198528982">(May 23 2020 at 10:25)</a>:</h4>
<blockquote>
<ul>
<li>Does ODR linkage adversely affect runtime performance?</li>
</ul>
</blockquote>
<p>All of {LinkOnce,Weak}{Any,ODR} block some interprocedural analyses and optimizations for reasons described here <a href="https://www.playingwithpointers.com/blog/ipo-and-derefinement.html">https://www.playingwithpointers.com/blog/ipo-and-derefinement.html</a><br>
If you want to know what it affects exactly in LLVM, <code>GlobalValue</code> has helper methods <code>hasExactDefinition</code> / <code>isDefinitionExact</code> which return false for those cases and ought to be used whenever this is relevant.</p>



<a name="198529491"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/198529491" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Nikita Popov <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#198529491">(May 23 2020 at 10:39)</a>:</h4>
<p>Thanks for the reference, that's pretty unfortunate.</p>



<a name="198531550"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/198531550" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> mati865 <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#198531550">(May 23 2020 at 11:43)</a>:</h4>
<p>Binutils (AS and LD BFD) are very buggy when it comes to weak symbols on MinGW. Clang doesn't yet allow weak symbols for MinGW (turns them into global symbols) but if you force it things seem to work just fine when using LLD.<br>
Even more, LLD can propely link objects with weak symbols created by GCC + Binutils AS.</p>



<a name="198532092"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/198532092" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> mati865 <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#198532092">(May 23 2020 at 12:01)</a>:</h4>
<p>Over 11 years old open issue: <a href="https://sourceware.org/bugzilla/show_bug.cgi?id=9687">https://sourceware.org/bugzilla/show_bug.cgi?id=9687</a></p>



<a name="198580319"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/198580319" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Amanieu <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#198580319">(May 24 2020 at 12:07)</a>:</h4>
<p>Weak symbols really only work on ELF.</p>



<a name="198661567"></a>
<h4><a href="https://rust-lang.zulipchat.com#narrow/stream/187780-t-compiler/wg-llvm/topic/Using%20ODR%20linkage%20for%20generics%3F/near/198661567" class="zl"><img src="https://rust-lang.github.io/zulip_archive/assets/img/zulip.svg" alt="view this post on Zulip" style="width:20px;height:20px;"></a> Björn Steinbrink <a href="https://rust-lang.github.io/zulip_archive/stream/187780-t-compiler/wg-llvm/topic/Using.20ODR.20linkage.20for.20generics.3F.html#198661567">(May 25 2020 at 12:15)</a>:</h4>
<p>weak_odr was used because back then (not sure if that would still be the case), the symbol might otherwise be optimized away, while other compilation units still depend on it, because the optimizer doesn't know about the other compilation units</p>



<hr><p>Last updated: Aug 07 2021 at 22:04 UTC</p>
</html>